package il.ac.tau.cg.ex3.parser.parametershander.lights;

import il.ac.tau.cg.ex3.entities.scene.Scene;
import il.ac.tau.cg.ex3.entities.scene.lights.AreaLight;
import il.ac.tau.cg.ex3.entities.styles.Color;
import il.ac.tau.cg.ex3.math.Point;
import il.ac.tau.cg.ex3.parser.Parser;
import il.ac.tau.cg.ex3.parser.Parser.ParseException;
import il.ac.tau.cg.ex3.parser.parametershander.EntityParametersHandler;

public class AreaLightParametersHandler extends EntityParametersHandler
{
	private Color color;
	private Point p0;
	private Point p1;
	private Point p2;
	private int dimension;
	
	public AreaLightParametersHandler()
	{
		super();
		
		color     = new Color(1.0, 1.0, 1.0);
		p0        = null;
		p1        = null;
		p2        = null;
		dimension = -1;
	}
	
	public boolean addParam(String key, String[] value) throws ParseException
	{	
		paramsCache.add(key);
		
		ELightParameters param =  ELightParameters.findParam(key);
		
		if (param == null)
		{
			return false;
		}
		
		Parser.pAssert((value.length == param.argsNum), param.name + " INVALID ARGS NUM");
		
		switch (param)
		{
			case COLOR:
			{	
				color = getColor(value);
			} break;

			case P0:
			{
				p0 = getPoint(value);
			} break;
				
			case P1:
			{
				p1 = getPoint(value);
			} break;	
			
			case P2:
			{
				p2 = getPoint(value);
			} break;
			
			case GRID_WIDTH:
			{
				dimension = Integer.parseInt(value[0]);
			} break;
		}
		
		return true;
	}

	protected void createEntity(Scene scene)
	{
		scene.addLight(new AreaLight(color, dimension, p0, p1, p2));
	}

	@Override
	protected boolean validateEntity() throws ParseException
	{
		for (ELightParameters param : ELightParameters.values())
		{
			if (param.isMandatory && !paramsCache.contains(param.name))
			{
				return false;
			}
		}
		
		return true;
	}
	
	private enum ELightParameters
	{
		/* LIGHTS ENTITIES*/
		COLOR("color", false, 3),
		
		/* LIGHT AREA ENTITIES */
		P0         ("p0", true, 3),
		P1         ("p1", true, 3),
		P2         ("p2", true, 3),
		GRID_WIDTH ("grid-width", true, 1);

		private final String  name;
		private final boolean isMandatory;
		private final int     argsNum;
		
		ELightParameters(String name, boolean isMandatory, int argsNum)
		{
			this.name = name;
			this.isMandatory = isMandatory;
			this.argsNum = argsNum;
		}
		
		public static ELightParameters findParam(String name)
		{
			for (ELightParameters param : ELightParameters.values())
			{
				if (param.name.equals(name))
				{
					return param;
				}
			}
			
			return null;
		}
	}
}
